package nf.translat.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

public class db{
    //声明Connection对象
    Connection con;
    //驱动程序名
    String driver = "com.mysql.jdbc.Driver";
    //URL指向要访问的数据库名mydata
    String url = "jdbc:mysql://localhost:3306/sqltestdb";
    //MySQL配置时的用户名
    String user = "root";
    //MySQL配置时的密码
    String password = "123456";

    public db(String[] args ) {
        if(!args[0].matches(".+:\\d+"))  args[0]+=":3306";
        url="jdbc:mysql://"+args[0]+"/"+args[1];
        user=args[2];
        password=args[3];
        open();
    }
    void open(){
        //加载驱动程序
        try {
            Class.forName(driver);
            //1.getConnection()方法，连接MySQL数据库！！
            con = DriverManager.getConnection(url,user,password);
            if(!con.isClosed()) System.out.println("Succeeded connecting to the Database:"+url);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static var Instance=new var();
    // 单例模式
    public static  db getInstance(String name) {
        return (db)Instance.get(name).source();
    }
    public static  boolean setInstance(String name,var args) {
        if (Instance.get(name) == null) {
                Instance.set(name, new db(args.toStrings()));
        }
        return true;
    }

    public var execute(String sql, Object[] params){
        try {
            if(sql.matches("^select .+|^SELECT .+")) {
                Statement statement = con.createStatement();
                ResultSet rs = statement.executeQuery(sql);
                return new iterator(rs);
            }else{
                PreparedStatement psql=con.prepareStatement(sql, (String[]) params);
                return var.valueOf(psql.executeUpdate());
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return var.valueOf(false);
        }
    }

    public void insert(String name,var params){
          String keys,values;
          keys=values="";
          for(var k : params){
              keys+=String.format("`%s`,",k.toString());
              values+=String.format("'%s',",params.get(k).toString());
          }
          String sql=String.format("insert into `%s` (%s) values (%s)",name,keys.substring(0,keys.length()-1),values.substring(0,values.length()-1));
          log.Info(sql);
          //execute(sql,null);
    }

    public var query(String sql) {
        return execute(sql,null);
    }

    public var queryId(String name, String where){
        var one= query("select * from "+name+where+"limit 1");
        return (var)one.get(0);
    }
    public Query find(){
        return new Query();
    }

    public var all(String s) {
        return execute("select * from "+s +" limit 10000",null);
    }

    public var findOne(String name, String where) {
          var one= query("select * from "+name+where+"limit 1");
          return one.get(0);
    }

    public static class Query {
         Query where(){
             return this;
         }
         Query andWhere(){
             return this;
         }

        Query orWhere(){
            return this;
        }
        Query limit(){
            return this;
        }
        Query order(){
            return this;
        }

        Query select(){
            return this;
        }

        Query groupBy(){
            return this;
        }


        var all(){
         return new var();
        }

        var one(){
            return new var();
        }

        int count(){
             return 0;
        }

        String filed(String name){
             return "";
        }

    }
    
    class iterator  extends var{
        private ResultSet rs;
        public iterator(ResultSet rs) {
            this.rs=rs;
            this.type=Types.IS_ARRAY;
        }
        
        protected void destroy(){
            try {
                rs.close();
            } catch (SQLException ex) {
                Logger.getLogger(db.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        @Override
        public boolean hasNext(){
            try {
                return rs.next();
            } catch (SQLException ex) {
                Logger.getLogger(db.class.getName()).log(Level.SEVERE, null, ex);
            }
            return false;
        }
        
        
        
        @Override
        public var next() {
            var row = new var();
            try {
                ResultSetMetaData rsmd = rs.getMetaData();
                for (int i = 0; i < rsmd.getColumnCount(); i++) {
                    String key = rsmd.getColumnName(i+1);
                    String value = rs.getString(key);
                    boolean r = row.set(key, var.valueOf(value));
                }
            } catch (SQLException ex) {
                Logger.getLogger(db.class.getName()).log(Level.SEVERE, null, ex);
            }
            return row;
        }
        
        public String toString(){
            for(var v : this){
                this.push(v);
            }
            return this.toString();
        }
    }
}